package com.ruoyi.business.statistics.service.impl;

import cn.hutool.core.util.StrUtil;
import com.ruoyi.business.seaTotal.mapper.SeaTotalDataMapper;
import com.ruoyi.business.statistics.domain.StatisticsData;
import com.ruoyi.business.statistics.service.ISeaStatisticsService;
import com.ruoyi.common.utils.DateUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.Year;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * @Description
 *
 * @author 李国臻
 * @date 2025-04-22 09:22
 */
@Service
public class SeaStatisticsServiceImpl implements ISeaStatisticsService {
    @Resource
    private SeaTotalDataMapper seaTotalDataMapper;
    @Override
    public List<StatisticsData> selectStatisticsDataList(StatisticsData statisticsData) {
        List<StatisticsData> resultList = new ArrayList<>();
        switch (statisticsData.getDateUnit()){
            case "0":
                computeData(statisticsData,resultList);
                break;
            case "1":
                //按月统计
                List<YearMonth> monthList = statisticsData.getMonthList();
                if (CollectionUtils.isNotEmpty(monthList)) {
                    monthList.forEach(month -> {
                        // 获取当月的第一天和最后一天
                        LocalDate startDate = month.atDay(1);
                        LocalDate endDate = month.atEndOfMonth();
                        statisticsData.setMonth(month);
                        getTime(startDate, endDate, statisticsData, resultList);
                    });
                }
                break;
            case "2":
                //按年统计
                List<Year> yearList = statisticsData.getYearList();
                if (CollectionUtils.isNotEmpty(yearList)) {
                    yearList.forEach(year -> {
                        // 获取该年的第一天和最后一天
                        LocalDate startOfYear = year.atDay(1); // 1月1日
                        LocalDate endOfYear = LocalDate.of(year.getValue(), 12, 31); // 12月31日
                        statisticsData.setYear(year);
                        getTime(startOfYear, endOfYear, statisticsData, resultList);
                    });
                }
                break;
        }

        return resultList;
    }
    private void getTime(LocalDate startOfYear, LocalDate endOfYear, StatisticsData statisticsData,  List<StatisticsData> resultList){
        // 格式化为字符串（可根据需要调整格式）
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

        String startDateTimeStr = startOfYear.format(formatter);
        String endDateTimeStr = endOfYear.format(formatter);

        // 设置回 statisticsData
        statisticsData.setStartDate(DateUtils.parseDate(startDateTimeStr));
        statisticsData.setEndDate(DateUtils.parseDate(endDateTimeStr));
        computeData(statisticsData,resultList);
    }
    private void computeData(StatisticsData statisticsData,  List<StatisticsData> resultList){
        StatisticsData resultStatisticsData=new StatisticsData();
        resultStatisticsData.setSelectParamsName(statisticsData.getSelectParamsName());
        resultStatisticsData.setBuoyName(statisticsData.getBuoyName());

        switch (statisticsData.getDateUnit()){
            case "0":
                resultStatisticsData.setDisplayDate(statisticsData.getStartDate().toString()+"-"+statisticsData.getEndDate().toString());
                break;
            case "1":
                resultStatisticsData.setDisplayDate(statisticsData.getMonth().toString());
                break;
            case "2":
                resultStatisticsData.setDisplayDate(statisticsData.getYear().toString());
                break;
        }
        //按天统计
        String selectParamsUnderline = StrUtil.toUnderlineCase(statisticsData.getSelectParams());
        statisticsData.setSelectParams(selectParamsUnderline);
        //数据量
        int totalCount = seaTotalDataMapper.selectNotNullDataCount(statisticsData);
        if(totalCount>0){
            List<Double> numericValues = seaTotalDataMapper.selectNotNullData(statisticsData);
            //数据量
            resultStatisticsData.setTotalCount(String.valueOf(totalCount));
            // 计算平均值
            double average = numericValues.stream()
                    .mapToDouble(Double::doubleValue)
                    .average()
                    .orElse(0.0);

            // 计算总和（用于后续计算方差）
            double sum = numericValues.stream()
                    .mapToDouble(Double::doubleValue)
                    .sum();

            // 计算方差
            double variance = numericValues.stream()
                    .mapToDouble(value -> Math.pow(value - average, 2))
                    .average()
                    .orElse(0.0);

            // 计算标准差
            double standardDeviation = Math.sqrt(variance);

            // 查找最大值
            double max = numericValues.stream()
                    .mapToDouble(Double::doubleValue)
                    .max()
                    .orElse(0.0);

            // 查找最小值
            double min = numericValues.stream()
                    .mapToDouble(Double::doubleValue)
                    .min()
                    .orElse(0.0);

            // 设置结果
            resultStatisticsData.setAverageCount(String.format("%.2f", average));
            resultStatisticsData.setVarianceCount(String.format("%.2f", variance));
            resultStatisticsData.setSdCount(String.format("%.2f", standardDeviation));
            resultStatisticsData.setMaxCount(String.valueOf(max));
            resultStatisticsData.setMinCount(String.valueOf(min));
        }else{
            resultStatisticsData.setTotalCount("/");
            resultStatisticsData.setAverageCount("/");
            resultStatisticsData.setVarianceCount("/");
            resultStatisticsData.setSdCount("/");
            resultStatisticsData.setMaxCount("/");
            resultStatisticsData.setMinCount("/");
        }
        resultList.add(resultStatisticsData);
    }

}
